from rest_framework import status, viewsets, permissions
from rest_framework.decorators import api_view, permission_classes, action
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from rest_framework.permissions import IsAuthenticated, AllowAny
from django.contrib.auth import login, logout
from django.utils import timezone
from django.db import transaction
from .models import User, UserProfile, LoginLog
from .serializers import (
    UserRegistrationSerializer,
    UserLoginSerializer,
    UserSerializer,
    UserProfileSerializer,
    PasswordChangeSerializer,
    LoginLogSerializer
)
from .utils import get_client_ip, parse_user_agent, create_login_log
from logwisdomhub.response import ApiResponse, ErrorCode  # 添加导入
import logging

logger = logging.getLogger('accounts')

@api_view(['POST'])
@permission_classes([AllowAny])
def register(request):
    """用户注册API"""
    try:
        with transaction.atomic():
            serializer = UserRegistrationSerializer(data=request.data)
            
            if not serializer.is_valid():
                logger.warning(f"用户注册数据验证失败: {serializer.errors}")
                return ApiResponse.error(
                    '注册信息验证失败',
                    ErrorCode.VALIDATION_ERROR,
                    serializer.errors,
                    status.HTTP_400_BAD_REQUEST
                )
            
            user = serializer.save()
            token, created = Token.objects.get_or_create(user=user)
            
            logger.info(f"新用户注册成功: {user.username} ({user.email})")
            
            create_login_log(
                user=user,
                request=request,
                status='success',
                action='register'
            )
            
            user_serializer = UserSerializer(user, context={'request': request})
            
            return ApiResponse.success({
                'user': user_serializer.data,
                'token': token.key
            }, '注册成功', ErrorCode.SUCCESS, status.HTTP_201_CREATED)
            
    except Exception as e:
        logger.error(f"用户注册失败: {str(e)}")
        return ApiResponse.error(
            f"注册失败: {str(e)}", 
            ErrorCode.DATABASE_ERROR,
            http_status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

@api_view(['POST'])
@permission_classes([AllowAny])
def login_view(request):
    """用户登录API"""
    try:
        serializer = UserLoginSerializer(data=request.data, context={'request': request})
        
        if not serializer.is_valid():
            return ApiResponse.error(
                '登录信息验证失败',
                ErrorCode.VALIDATION_ERROR,
                serializer.errors,
                status.HTTP_400_BAD_REQUEST
            )
        
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        
        # 更新最后登录时间
        user.last_login = timezone.now()
        user.save(update_fields=['last_login'])
        
        # 创建登录日志
        create_login_log(
            user=user,
            request=request,
            status='success',
            action='login'
        )
        
        logger.info(f"用户登录成功: {user.username}")
        
        user_serializer = UserSerializer(user, context={'request': request})
        
        return ApiResponse.success({
            'user': user_serializer.data,
            'token': token.key
        }, '登录成功')
        
    except Exception as e:
        logger.error(f"用户登录失败: {str(e)}")
        return ApiResponse.error(
            f"登录失败: {str(e)}", 
            ErrorCode.AUTHENTICATION_ERROR,
            http_status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def logout_view(request):
    """用户登出API"""
    try:
        # 删除用户的认证令牌
        try:
            token = Token.objects.get(user=request.user)
            token.delete()
        except Token.DoesNotExist:
            pass
        
        # 创建登出日志
        create_login_log(
            user=request.user,
            request=request,
            status='success',
            action='logout'
        )
        
        logger.info(f"用户登出成功: {request.user.username}")
        
        return ApiResponse.success(None, '登出成功')
        
    except Exception as e:
        logger.error(f"用户登出失败: {str(e)}")
        return ApiResponse.error(
            f"登出失败: {str(e)}", 
            ErrorCode.GENERAL_ERROR,
            http_status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        """
        获取查询集
        
        普通用户只能查看自己的信息，管理员可以查看所有用户
        """
        if self.request.user.is_staff:
            return User.objects.all()
        return User.objects.filter(id=self.request.user.id)
    
    def get_object(self):
        """
        获取当前用户对象
        
        如果URL中没有指定用户ID，默认返回当前登录用户
        """
        if self.kwargs.get('pk') == 'me' or not self.kwargs.get('pk'):
            return self.request.user
        return super().get_object()
    
    @action(detail=False, methods=['get', 'put', 'patch'])
    def profile(self, request):
        """用户资料管理"""
        try:
            user = request.user
            profile, created = UserProfile.objects.get_or_create(user=user)
            
            if request.method == 'GET':
                user_serializer = UserSerializer(user, context={'request': request})
                profile_serializer = UserProfileSerializer(profile)
                
                return ApiResponse.success({
                    'user': user_serializer.data,
                    'profile': profile_serializer.data
                }, '获取用户资料成功')
            
            elif request.method in ['PUT', 'PATCH']:
                partial = request.method == 'PATCH'
                serializer = UserProfileSerializer(
                    profile,
                    data=request.data,
                    partial=partial,
                    context={'request': request}
                )
                
                if serializer.is_valid():
                    serializer.save()
                    logger.info(f"用户资料更新: {request.user.username}")
                    
                    return ApiResponse.success({
                        'user': user_serializer.data,
                        'profile': profile_serializer.data
                    }, '更新用户资料成功')
                    
        except Exception as e:
            logger.error(f"用户资料操作失败: {str(e)}")
            return ApiResponse.error(
                f"用户资料操作失败: {str(e)}", 
                ErrorCode.DATABASE_ERROR,
                http_status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'])
    def change_password(self, request):
        """修改密码"""
        try:
            serializer = PasswordChangeSerializer(
                data=request.data, 
                context={'request': request}
            )
            
            if not serializer.is_valid():
                return ApiResponse.error(
                    '密码验证失败',
                    ErrorCode.VALIDATION_ERROR,
                    serializer.errors,
                    status.HTTP_400_BAD_REQUEST
                )
            
            user = request.user
            user.set_password(serializer.validated_data['new_password'])
            user.save()
            
            # 删除现有token，强制重新登录
            Token.objects.filter(user=user).delete()
            
            logger.info(f"用户修改密码成功: {user.username}")
            
            return ApiResponse.success(None, '密码修改成功，请重新登录')
            
        except Exception as e:
            logger.error(f"修改密码失败: {str(e)}")
            return ApiResponse.error(
                f"修改密码失败: {str(e)}", 
                ErrorCode.DATABASE_ERROR,
                http_status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def login_logs(self, request):
        """获取登录日志"""
        try:
            logs = LoginLog.objects.filter(user=request.user).order_by('-created_at')
            
            page = self.paginate_queryset(logs)
            if page is not None:
                serializer = LoginLogSerializer(page, many=True)
                paginated_data = self.get_paginated_response(serializer.data).data
                return ApiResponse.paginated_success(paginated_data, "获取登录日志成功")
            
            serializer = LoginLogSerializer(logs, many=True)
            return ApiResponse.success({
                'results': serializer.data,
                'count': len(serializer.data)
            }, "获取登录日志成功")
            
        except Exception as e:
            logger.error(f"获取登录日志失败: {str(e)}")
            return ApiResponse.error(
                f"获取登录日志失败: {str(e)}", 
                ErrorCode.DATABASE_ERROR,
                http_status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )